<template>
  <div class="dashboard-container">
    <!-- 顶部区域 -->
    <div class="dashboard-header">
      <div class="flex justify-between items-center mb-6">
        <div class="flex items-center">
          <h2 class="text-2xl font-bold mr-4 dark:text-white">
            酒店运营控制台
          </h2>
          <a-tag>{{ timeRangeText }}数据</a-tag>
        </div>
        <div class="flex items-center space-x-4">
          <a-radio-group type="button" v-model="timeRange" size="large">
            <a-radio value="today">今日</a-radio>
            <a-radio value="week">本周</a-radio>
            <a-radio value="month">本月</a-radio>
            <a-radio value="year">本年</a-radio>
          </a-radio-group>
          <a-button type="outline" @click="refreshData">
            <template #icon><icon-refresh /></template>
            刷新数据
          </a-button>
        </div>
      </div>
    </div>

    <!-- 主体内容区域 -->
    <div class="dashboard-content">
      <!-- 数据概览卡片（顶部全宽） -->
      <div class="data-overview-cards w-full">
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
          <!-- 营业收入 -->
          <a-card class="stat-card revenue-card">
            <div class="flex items-center justify-between">
              <div>
                <div class="text-gray-500 dark:text-gray-300 mb-2">
                  营业收入
                </div>
                <div
                  class="text-2xl font-bold text-blue-600 dark:text-blue-300"
                >
                  ¥{{ formatNumber(stats.revenue) }}
                </div>
                <div class="mt-2 text-sm flex items-center">
                  <span
                    :class="
                      stats.revenueGrowth >= 0
                        ? 'text-green-600 dark:text-green-400'
                        : 'text-red-600 dark:text-red-400'
                    "
                    class="flex items-center"
                  >
                    <icon-up v-if="stats.revenueGrowth >= 0" />
                    <icon-down v-else />
                    {{ Math.abs(stats.revenueGrowth) }}%
                  </span>
                  <span class="ml-1 text-gray-500 dark:text-gray-400"
                    >较上期</span
                  >
                </div>
              </div>
              <div class="stat-icon revenue-icon">
                <icon-money-circle />
              </div>
            </div>
            <div class="stat-footer">
              <div
                class="flex justify-between text-sm text-gray-500 dark:text-gray-400"
              >
                <span>日均收入</span>
                <span class="font-medium text-blue-600 dark:text-blue-300">
                  ¥{{ formatNumber(stats.revenue / 30) }}
                </span>
              </div>
            </div>
          </a-card>

          <!-- 订单数量 -->
          <a-card class="stat-card orders-card">
            <div class="flex items-center justify-between">
              <div>
                <div class="text-gray-500 dark:text-gray-300 mb-2">
                  订单数量
                </div>
                <div
                  class="text-2xl font-bold text-green-600 dark:text-green-300"
                >
                  {{ formatNumber(stats.orderCount) }}
                </div>
                <div class="mt-2 text-sm flex items-center">
                  <span
                    :class="
                      stats.orderGrowth >= 0
                        ? 'text-green-600 dark:text-green-400'
                        : 'text-red-600 dark:text-red-400'
                    "
                    class="flex items-center"
                  >
                    <icon-up v-if="stats.orderGrowth >= 0" />
                    <icon-down v-else />
                    {{ Math.abs(stats.orderGrowth) }}%
                  </span>
                  <span class="ml-1 text-gray-500 dark:text-gray-400"
                    >较上期</span
                  >
                </div>
              </div>
              <div class="stat-icon orders-icon">
                <icon-file />
              </div>
            </div>
            <div class="stat-footer">
              <div
                class="flex justify-between text-sm text-gray-500 dark:text-gray-400"
              >
                <span>完成率</span>
                <span class="font-medium text-green-600 dark:text-green-300">
                  {{ stats.orderCompletionRate }}%
                </span>
              </div>
            </div>
          </a-card>

          <!-- 入住率 -->
          <a-card class="stat-card occupancy-card">
            <div class="flex items-center justify-between">
              <div>
                <div class="text-gray-500 dark:text-gray-300 mb-2">入住率</div>
                <div
                  class="text-2xl font-bold text-purple-600 dark:text-purple-300"
                >
                  {{ stats.occupancyRate }}%
                </div>
                <div class="mt-2 text-sm flex items-center">
                  <span
                    :class="
                      stats.occupancyGrowth >= 0
                        ? 'text-green-600 dark:text-green-400'
                        : 'text-red-600 dark:text-red-400'
                    "
                    class="flex items-center"
                  >
                    <icon-up v-if="stats.occupancyGrowth >= 0" />
                    <icon-down v-else />
                    {{ Math.abs(stats.occupancyGrowth) }}%
                  </span>
                  <span class="ml-1 text-gray-500 dark:text-gray-400"
                    >较上期</span
                  >
                </div>
              </div>
              <div class="stat-icon occupancy-icon">
                <icon-home />
              </div>
            </div>
            <div class="stat-footer">
              <div
                class="flex justify-between text-sm text-gray-500 dark:text-gray-400"
              >
                <span>空房率</span>
                <span class="font-medium text-purple-600 dark:text-purple-300">
                  {{ 100 - stats.occupancyRate }}%
                </span>
              </div>
            </div>
          </a-card>

          <!-- 新增用户 -->
          <a-card class="stat-card members-card">
            <div class="flex items-center justify-between">
              <div>
                <div class="text-gray-500 dark:text-gray-300 mb-2">
                  新增用户
                </div>
                <div
                  class="text-2xl font-bold text-orange-600 dark:text-orange-300"
                >
                  {{ formatNumber(stats.newMembers) }}
                </div>
                <div class="mt-2 text-sm flex items-center">
                  <span
                    :class="
                      stats.memberGrowth >= 0
                        ? 'text-green-600 dark:text-green-400'
                        : 'text-red-600 dark:text-red-400'
                    "
                    class="flex items-center"
                  >
                    <icon-up v-if="stats.memberGrowth >= 0" />
                    <icon-down v-else />
                    {{ Math.abs(stats.memberGrowth) }}%
                  </span>
                  <span class="ml-1 text-gray-500 dark:text-gray-400"
                    >较上期</span
                  >
                </div>
              </div>
              <div class="stat-icon members-icon">
                <icon-user-group />
              </div>
            </div>
            <div class="stat-footer">
              <div
                class="flex justify-between text-sm text-gray-500 dark:text-gray-400"
              >
                <span>用户总数</span>
                <span class="font-medium text-orange-600 dark:text-orange-300">
                  {{ formatNumber(stats.totalMembers) }}
                </span>
              </div>
            </div>
          </a-card>
        </div>
      </div>

      <!-- 内容区域分为左侧主区域和右侧侧边栏 -->
      <div class="dashboard-main-container mt-6">
        <!-- 左侧主要内容区域 -->
        <div class="dashboard-main">
          <!-- 主要图表区域 -->
          <div class="main-charts">
            <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
              <!-- 收入趋势图 -->
              <a-card class="chart-card">
                <template #title>
                  <div class="flex items-center justify-between">
                    <div class="flex items-center">
                      <div class="text-lg font-medium dark:text-white">
                        收入趋势
                      </div>
                      <a-tooltip content="展示每日营业收入变化趋势">
                        <icon-info-circle
                          class="ml-2 text-gray-400 dark:text-gray-500"
                        />
                      </a-tooltip>
                    </div>
                    <div class="flex items-center space-x-4">
                      <a-select v-model="revenueTrendType" style="width: 120px">
                        <a-option value="day">按日</a-option>
                        <a-option value="week">按周</a-option>
                        <a-option value="month">按月</a-option>
                      </a-select>
                      <a-button type="text" size="small">
                        <template #icon><icon-download /></template>
                        导出数据
                      </a-button>
                    </div>
                  </div>
                </template>
                <div id="revenueChartRef" class="chart-container"></div>
              </a-card>

              <!-- 房型分析 -->
              <a-card class="chart-card">
                <template #title>
                  <div class="flex items-center justify-between">
                    <div class="flex items-center">
                      <div class="text-lg font-medium dark:text-white">
                        房型分析
                      </div>
                      <a-tooltip content="展示各类房型的入住率和收入分析">
                        <icon-info-circle
                          class="ml-2 text-gray-400 dark:text-gray-500"
                        />
                      </a-tooltip>
                    </div>
                    <a-select v-model="roomAnalysisType" style="width: 120px">
                      <a-option value="occupancy">入住率</a-option>
                      <a-option value="revenue">收入占比</a-option>
                    </a-select>
                  </div>
                </template>
                <div id="roomTypeChartRef" class="chart-container"></div>
              </a-card>
            </div>

            <!-- 酒店运营指标和订单趋势 -->
            <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
              <!-- 酒店运营指标五角图 -->
              <a-card class="chart-card" title="酒店运营指标">
                <div id="businessIndicatorRef" class="chart-container"></div>
              </a-card>

              <!-- 订单趋势 -->
              <a-card class="chart-card" title="订单趋势">
                <template #extra>
                  <a-select
                    v-model="orderTrendTimeRange"
                    size="small"
                    style="width: 100px"
                  >
                    <a-option value="week">本周</a-option>
                    <a-option value="month">本月</a-option>
                    <a-option value="year">本年</a-option>
                  </a-select>
                </template>
                <div id="orderChartRef" class="chart-container"></div>
              </a-card>
            </div>

            <!-- 客户分析和客源地区分析 -->
            <div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
              <!-- 客户分析 -->
              <a-card class="chart-card" title="客户分析">
                <template #extra>
                  <a-tabs type="text" v-model="userAnalysisTab">
                    <a-tab-pane key="age" title="年龄分布"></a-tab-pane>
                    <a-tab-pane key="gender" title="性别比例"></a-tab-pane>
                  </a-tabs>
                </template>
                <div id="userChartRef" class="chart-container"></div>
              </a-card>

              <!-- 客源地区分析 -->
              <a-card
                class="chart-card map-chart-card col-span-2"
                title="客源地区分析"
              >
                <template #extra>
                  <div class="flex items-center">
                    <a-select
                      v-model="regionTimeRange"
                      size="small"
                      style="width: 100px; margin-right: 10px"
                    >
                      <a-option value="week">本周</a-option>
                      <a-option value="month">本月</a-option>
                      <a-option value="year">本年</a-option>
                    </a-select>
                    <a-radio-group type="button" v-model="mapType" size="small">
                      <a-radio value="china">全国</a-radio>
                      <a-radio value="guangxi">广西</a-radio>
                    </a-radio-group>
                    <a-button
                      type="text"
                      size="small"
                      @click="showMapSettings = !showMapSettings"
                    >
                      <template #icon><icon-settings /></template>
                    </a-button>
                  </div>
                </template>
                <div class="map-settings-panel" v-if="showMapSettings">
                  <div class="flex justify-between items-center mb-3">
                    <div class="text-lg font-medium">
                      {{
                        mapType === "china" ? "全国地图设置" : "广西地图设置"
                      }}
                    </div>
                    <div>
                      <a-button
                        size="small"
                        type="outline"
                        status="warning"
                        @click="resetMapSettings"
                      >
                        重置设置
                      </a-button>
                      <a-button
                        size="small"
                        type="primary"
                        class="ml-2"
                        @click="showMapSettings = false"
                      >
                        关闭设置
                      </a-button>
                    </div>
                  </div>
                  <div v-if="mapType === 'china'" class="map-settings-content">
                    <div class="settings-title">地图位置</div>
                    <div class="settings-row">
                      <span class="settings-label">缩放比例：</span>
                      <a-slider
                        v-model="chinaMapZoom"
                        :min="0.8"
                        :max="2.5"
                        :step="0.1"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="chinaMapZoom"
                        :min="0.8"
                        :max="2.5"
                        :step="0.1"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                    <div class="settings-row">
                      <span class="settings-label">中心经度：</span>
                      <a-slider
                        v-model="chinaMapCenter[0]"
                        :min="90"
                        :max="120"
                        :step="0.5"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="chinaMapCenter[0]"
                        :min="90"
                        :max="120"
                        :step="0.5"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                    <div class="settings-row">
                      <span class="settings-label">中心纬度：</span>
                      <a-slider
                        v-model="chinaMapCenter[1]"
                        :min="20"
                        :max="45"
                        :step="0.5"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="chinaMapCenter[1]"
                        :min="20"
                        :max="45"
                        :step="0.5"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                    <div class="settings-row">
                      <span class="settings-label">Y轴偏移：</span>
                      <a-slider
                        v-model="chinaMapOffsetY"
                        :min="-10"
                        :max="10"
                        :step="0.5"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="chinaMapOffsetY"
                        :min="-10"
                        :max="10"
                        :step="0.5"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                    <div class="settings-title mt-3">南海诸岛设置</div>
                    <div class="settings-row">
                      <span class="settings-label">左右位置：</span>
                      <a-slider
                        v-model="nanHaiPositionLeft"
                        :min="50"
                        :max="90"
                        :step="1"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="nanHaiPositionLeft"
                        :min="50"
                        :max="90"
                        :step="1"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                    <div class="settings-row">
                      <span class="settings-label">上下位置：</span>
                      <a-slider
                        v-model="nanHaiPositionTop"
                        :min="60"
                        :max="95"
                        :step="1"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="nanHaiPositionTop"
                        :min="60"
                        :max="95"
                        :step="1"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                    <div class="settings-row">
                      <span class="settings-label">显示大小：</span>
                      <a-slider
                        v-model="nanHaiSizeNum"
                        :min="5"
                        :max="25"
                        :step="1"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="nanHaiSizeNum"
                        :min="5"
                        :max="25"
                        :step="1"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                  </div>
                  <div v-else class="map-settings-content">
                    <div class="settings-title">地图位置</div>
                    <div class="settings-row">
                      <span class="settings-label">中心经度：</span>
                      <a-slider
                        v-model="guangxiMapCenter[0]"
                        :min="105"
                        :max="112"
                        :step="0.1"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="guangxiMapCenter[0]"
                        :min="105"
                        :max="112"
                        :step="0.1"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                    <div class="settings-row">
                      <span class="settings-label">中心纬度：</span>
                      <a-slider
                        v-model="guangxiMapCenter[1]"
                        :min="21"
                        :max="26"
                        :step="0.1"
                        style="width: 150px"
                      />
                      <a-input-number
                        v-model="guangxiMapCenter[1]"
                        :min="21"
                        :max="26"
                        :step="0.1"
                        size="small"
                        style="width: 70px"
                      />
                    </div>
                  </div>
                </div>
                <div class="map-wrapper">
                  <div
                    id="regionChartRef"
                    class="chart-container map-container"
                  ></div>
                  <div class="map-loading" v-if="mapLoading">
                    <a-spin dot />
                    <div class="mt-2">地图数据加载中...</div>
                  </div>
                </div>
              </a-card>
            </div>
          </div>
        </div>

        <!-- 右侧边栏 -->
        <div class="dashboard-sidebar">
          <!-- 实时动态 -->
          <a-card class="sidebar-card">
            <template #title>
              <div class="flex items-center justify-between">
                <div class="flex items-center">
                  <div class="text-lg font-medium dark:text-white">
                    实时动态
                  </div>
                  <a-badge
                    :count="activities.length"
                    :dot="true"
                    class="ml-2"
                  />
                </div>
                <div class="flex items-center space-x-2">
                  <a-select v-model="activityFilter" style="width: 100px">
                    <a-option value="all">全部</a-option>
                    <a-option value="check-in">入住</a-option>
                    <a-option value="check-out">退房</a-option>
                    <a-option value="order">订单</a-option>
                    <a-option value="member">会员</a-option>
                    <a-option value="review">评价</a-option>
                  </a-select>
                  <a-button type="text" @click="refreshActivities">
                    <template #icon><icon-refresh /></template>
                    刷新
                  </a-button>
                </div>
              </div>
            </template>
            <a-timeline>
              <a-timeline-item
                v-for="activity in filteredActivities"
                :key="activity.id"
                :dot-color="getActivityColor(activity.type)"
              >
                <div class="flex justify-between items-start">
                  <div>
                    <span class="font-medium">{{ activity.content }}</span>
                    <div class="text-sm text-gray-500 mt-1">
                      {{ activity.details }}
                    </div>
                  </div>
                  <span class="text-sm text-gray-400">{{ activity.time }}</span>
                </div>
              </a-timeline-item>
            </a-timeline>
          </a-card>

          <!-- 待办事项 -->
          <a-card class="sidebar-card mt-4">
            <template #title>
              <div class="flex items-center justify-between">
                <div class="flex items-center">
                  <div class="text-lg font-medium dark:text-white">
                    待办事项
                  </div>
                  <a-badge :count="uncompletedTodos.length" class="ml-2" />
                </div>
                <div class="flex items-center space-x-2">
                  <a-select v-model="todoFilter" style="width: 100px">
                    <a-option value="all">全部</a-option>
                    <a-option value="pending">待办</a-option>
                    <a-option value="completed">已完成</a-option>
                  </a-select>
                  <a-button type="text" @click="showAddTodoModal = true">
                    <template #icon><icon-plus /></template>
                    添加
                  </a-button>
                </div>
              </div>
            </template>
            <div class="space-y-4">
              <div
                v-for="todo in filteredTodos"
                :key="todo.id"
                class="todo-item"
              >
                <div class="flex items-center flex-1 mr-4">
                  <a-checkbox
                    v-model="todo.completed"
                    @change="handleTodoStatusChange(todo)"
                  >
                    <span
                      :class="{ 'line-through text-gray-400': todo.completed }"
                    >
                      {{ todo.content }}
                    </span>
                  </a-checkbox>
                  <a-tag
                    v-if="todo.priority"
                    :color="getPriorityColor(todo.priority)"
                    class="ml-2"
                  >
                    {{ getPriorityText(todo.priority) }}
                  </a-tag>
                </div>
                <div class="flex items-center space-x-3">
                  <span
                    class="text-sm"
                    :class="
                      isDeadlineNear(todo.deadline)
                        ? 'text-red-500'
                        : 'text-gray-400'
                    "
                  >
                    {{ formatDeadline(todo.deadline) }}
                  </span>
                  <a-dropdown>
                    <a-button type="text" size="small">
                      <template #icon><icon-more-vertical /></template>
                    </a-button>
                    <template #content>
                      <a-doption @click="editTodo(todo)">编辑</a-doption>
                      <a-doption @click="deleteTodo(todo)">删除</a-doption>
                    </template>
                  </a-dropdown>
                </div>
              </div>
            </div>
          </a-card>

          <!-- AI智能分析 -->
          <a-card class="sidebar-card mt-4">
            <template #title>
              <div class="flex items-center justify-between">
                <div class="flex items-center">
                  <div class="text-lg font-medium dark:text-white">
                    AI智能分析
                  </div>
                  <el-icon class="ml-2 text-blue-500"
                    ><ChatLineRound
                  /></el-icon>
                </div>
                <el-button
                  type="primary"
                  size="small"
                  :loading="aiAnalysisLoading"
                  @click="generateAIAnalysis"
                >
                  <el-icon class="mr-1"><Connection /></el-icon>
                  生成分析
                </el-button>
              </div>
            </template>
            <div class="ai-analysis-content">
              <div
                v-if="aiAnalysisResult"
                class="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg"
              >
                <div class="flex justify-between mb-2">
                  <div class="text-sm text-gray-500">
                    <el-icon class="mr-1"><Timer /></el-icon>
                    分析时间: {{ aiAnalysisTime }}
                  </div>
                </div>
                <p class="whitespace-pre-line text-gray-700 dark:text-gray-300">
                  {{ aiAnalysisResult }}
                </p>
              </div>
              <el-empty
                v-else
                description='暂无AI分析记录，点击"生成分析"按钮开始智能分析'
              ></el-empty>
            </div>
          </a-card>
        </div>
      </div>
    </div>

    <!-- 添加待办事项弹窗 -->
    <a-modal
      v-model:visible="showAddTodoModal"
      title="添加待办事项"
      @ok="handleAddTodo"
      @cancel="resetTodoForm"
    >
      <a-form :model="todoForm" layout="vertical">
        <a-form-item field="content" label="内容" required>
          <a-input
            v-model="todoForm.content"
            placeholder="请输入待办事项内容"
            allow-clear
          />
        </a-form-item>
        <a-form-item field="priority" label="优先级">
          <a-select v-model="todoForm.priority">
            <a-option value="high">高</a-option>
            <a-option value="medium">中</a-option>
            <a-option value="low">低</a-option>
          </a-select>
        </a-form-item>
        <a-form-item field="deadline" label="截止时间">
          <a-date-picker
            v-model="todoForm.deadline"
            show-time
            format="YYYY-MM-DD HH:mm"
          />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup>
import {
  ref,
  onMounted,
  onUnmounted,
  reactive,
  nextTick,
  computed,
  watch,
} from "vue";
import * as echarts from "echarts";
import { Message } from "@arco-design/web-vue";
import dayjs from "dayjs";
import {
  IconMoneyCircle,
  IconFile,
  IconHome,
  IconUserGroup,
  IconInfoCircle,
  IconRefresh,
  IconPlus,
  IconUp,
  IconDown,
  IconMoreVertical,
  IconSettings,
} from "@arco-design/web-vue/es/icon";
import { ChatLineRound, Connection, Timer } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";

// 时间范围选择
const timeRange = ref("today");
const revenueTrendType = ref("day");
const roomAnalysisType = ref("occupancy");
const activityFilter = ref("all");
const todoFilter = ref("all");
const regionTimeRange = ref("week");
const mapType = ref("guangxi");
const userAnalysisTab = ref("age");
const orderTrendTimeRange = ref("week");
const mapDataType = ref("source");

// 地图控制参数
const chinaMapZoom = ref(1.5); // 全国地图缩放比例
const chinaMapOffsetY = ref(-2); // 全国地图Y轴偏移量（正值向下移动）
const chinaMapCenter = ref([104.5, 36.5]); // 全国地图中心位置，默认中国地理中心
const guangxiMapCenter = ref([108.320004, 23.82402]); // 广西地图中心位置
const nanHaiPosition = ref(["80%", "85%"]); // 南海诸岛位置 [左右位置, 上下位置]
const nanHaiSize = ref("15%"); // 南海诸岛大小

// 地图数据集
const chinaData = [
  { name: "广东省", value: 320, percentage: 18.5 },
  { name: "广西壮族自治区", value: 280, percentage: 16.2 },
  { name: "湖南省", value: 200, percentage: 11.6 },
  { name: "贵州省", value: 180, percentage: 10.4 },
  { name: "四川省", value: 160, percentage: 9.3 },
  { name: "云南省", value: 140, percentage: 8.1 },
  { name: "江西省", value: 120, percentage: 7.0 },
  { name: "福建省", value: 100, percentage: 5.8 },
  { name: "浙江省", value: 90, percentage: 5.2 },
  { name: "北京市", value: 80, percentage: 4.6 },
  { name: "上海市", value: 70, percentage: 4.1 },
  { name: "重庆市", value: 65, percentage: 3.8 },
  { name: "湖北省", value: 60, percentage: 3.5 },
  { name: "安徽省", value: 55, percentage: 3.2 },
  { name: "江苏省", value: 50, percentage: 2.9 },
  { name: "河南省", value: 45, percentage: 2.6 },
  { name: "山东省", value: 40, percentage: 2.3 },
  { name: "河北省", value: 35, percentage: 2.0 },
  { name: "辽宁省", value: 30, percentage: 1.7 },
  { name: "吉林省", value: 25, percentage: 1.5 },
  { name: "黑龙江省", value: 20, percentage: 1.2 },
  { name: "陕西省", value: 18, percentage: 1.0 },
  { name: "甘肃省", value: 15, percentage: 0.9 },
  { name: "新疆维吾尔自治区", value: 12, percentage: 0.7 },
  { name: "内蒙古自治区", value: 10, percentage: 0.6 },
  { name: "山西省", value: 8, percentage: 0.5 },
  { name: "天津市", value: 7, percentage: 0.4 },
  { name: "宁夏回族自治区", value: 5, percentage: 0.3 },
  { name: "青海省", value: 3, percentage: 0.2 },
  { name: "西藏自治区", value: 2, percentage: 0.1 },
  { name: "海南省", value: 25, percentage: 1.5 },
  { name: "香港特别行政区", value: 30, percentage: 1.7 },
  { name: "澳门特别行政区", value: 15, percentage: 0.9 },
  { name: "台湾省", value: 10, percentage: 0.6 },
];

const guangxiData = [
  { name: "南宁市", value: 120, percentage: 25.3 },
  { name: "桂林市", value: 100, percentage: 21.1 },
  { name: "贵港市", value: 80, percentage: 16.8 },
  { name: "柳州市", value: 60, percentage: 12.6 },
  { name: "玉林市", value: 50, percentage: 10.5 },
  { name: "北海市", value: 40, percentage: 8.4 },
  { name: "钦州市", value: 30, percentage: 6.3 },
  { name: "防城港市", value: 20, percentage: 4.2 },
  { name: "崇左市", value: 18, percentage: 3.8 },
  { name: "百色市", value: 16, percentage: 3.4 },
  { name: "河池市", value: 14, percentage: 2.9 },
  { name: "来宾市", value: 12, percentage: 2.5 },
  { name: "贺州市", value: 10, percentage: 2.1 },
  { name: "梧州市", value: 8, percentage: 1.7 },
];

// 计算属性 - 时间范围文本
const timeRangeText = computed(() => {
  switch (timeRange.value) {
    case "today":
      return "今日";
    case "week":
      return "本周";
    case "month":
      return "本月";
    case "year":
      return "本年";
    default:
      return "今日";
  }
});

// 统计数据
const stats = reactive({
  revenue: 26800,
  revenueGrowth: 12.5,
  orderCount: 168,
  orderGrowth: 8.3,
  occupancyRate: 85,
  occupancyGrowth: 5.2,
  newMembers: 24,
  memberGrowth: 15.6,
  orderCompletionRate: 95,
  totalMembers: 1280,
});

// 图表实例
let revenueChart = null;
let roomTypeChart = null;
let regionChart = null;
let userChart = null;
let orderChart = null;
let businessIndicatorChart = null;

// 实时动态数据
const activities = ref([
  {
    id: 1,
    type: "check-in",
    content: "张三办理入住",
    details: "房间号801，入住2晚",
    time: "10分钟前",
  },
  {
    id: 2,
    type: "order",
    content: "新增订单 #20240228001",
    details: "豪华大床房，2024-03-01至2024-03-03",
    time: "30分钟前",
  },
  {
    id: 3,
    type: "member",
    content: "新会员注册：李四",
    details: "手机号：138****8888",
    time: "1小时前",
  },
  {
    id: 4,
    type: "review",
    content: "收到新的评价",
    details: "房间整洁，服务周到，评分5星",
    time: "2小时前",
  },
  {
    id: 5,
    type: "check-out",
    content: "王五办理退房",
    details: "房间号603，消费金额￥888",
    time: "3小时前",
  },
]);

// 待办事项数据
const todos = ref([
  {
    id: 1,
    content: "检查并确认今日预订入住客人信息",
    completed: false,
    priority: "high",
    deadline: "2024-02-28 14:00",
  },
  {
    id: 2,
    content: "回复客户咨询邮件",
    completed: true,
    priority: "medium",
    deadline: "2024-02-28 16:00",
  },
  {
    id: 3,
    content: "审核新员工入职材料",
    completed: false,
    priority: "low",
    deadline: "2024-02-28 18:00",
  },
  {
    id: 4,
    content: "准备月度工作报告",
    completed: false,
    priority: "high",
    deadline: "2024-02-29 18:00",
  },
]);

// 待办事项表单
const showAddTodoModal = ref(false);
const todoForm = reactive({
  content: "",
  priority: "medium",
  deadline: "",
});

// 计算属性
const filteredActivities = computed(() => {
  if (activityFilter.value === "all") return activities.value;
  return activities.value.filter(
    (activity) => activity.type === activityFilter.value,
  );
});

const filteredTodos = computed(() => {
  if (todoFilter.value === "all") return todos.value;
  const isCompleted = todoFilter.value === "completed";
  return todos.value.filter((todo) => todo.completed === isCompleted);
});

const uncompletedTodos = computed(() => {
  return todos.value.filter((todo) => !todo.completed);
});

// 方法
const formatNumber = (num) => {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};

const refreshData = async () => {
  Message.success("数据已更新");
};

const refreshActivities = async () => {
  Message.success("动态已更新");
};

const handleTodoStatusChange = (todo) => {
  Message.success(`${todo.completed ? "完成" : "取消完成"}：${todo.content}`);
};

const handleAddTodo = () => {
  if (!todoForm.content) {
    Message.error("请输入待办事项内容");
    return;
  }

  todos.value.unshift({
    id: Date.now(),
    content: todoForm.content,
    priority: todoForm.priority,
    deadline: todoForm.deadline,
    completed: false,
  });

  showAddTodoModal.value = false;
  resetTodoForm();
  Message.success("添加成功");
};

const resetTodoForm = () => {
  todoForm.content = "";
  todoForm.priority = "medium";
  todoForm.deadline = "";
};

const editTodo = (todo) => {
  // 实现编辑功能
};

const deleteTodo = (todo) => {
  todos.value = todos.value.filter((t) => t.id !== todo.id);
  Message.success("删除成功");
};

const isDeadlineNear = (deadline) => {
  const now = dayjs();
  const deadlineTime = dayjs(deadline);
  return deadlineTime.diff(now, "hour") <= 24 && deadlineTime.isAfter(now);
};

const formatDeadline = (deadline) => {
  const deadlineTime = dayjs(deadline);
  const now = dayjs();

  if (deadlineTime.isSame(now, "day")) {
    return deadlineTime.format("HH:mm");
  }
  if (deadlineTime.isSame(now.add(1, "day"), "day")) {
    return "明天 " + deadlineTime.format("HH:mm");
  }
  return deadlineTime.format("MM-DD HH:mm");
};

// 获取活动类型颜色
const getActivityColor = (type) => {
  const colors = {
    "check-in": "blue",
    "check-out": "green",
    order: "orange",
    member: "purple",
    review: "red",
  };
  return colors[type] || "gray";
};

// 获取优先级颜色
const getPriorityColor = (priority) => {
  const colors = {
    high: "red",
    medium: "orange",
    low: "blue",
  };
  return colors[priority];
};

// 获取优先级文本
const getPriorityText = (priority) => {
  const texts = {
    high: "高",
    medium: "中",
    low: "低",
  };
  return texts[priority];
};

// 计算属性 - 地区排名前5
const topRegions = computed(() => {
  // 根据地图类型获取基础数据
  const baseData = mapType.value === "china" ? chinaData : guangxiData;

  // 根据数据类型和时间范围生成不同的排序数据
  let sortedData;
  if (mapDataType.value === "source") {
    sortedData = [...baseData].sort((a, b) => b.value - a.value);
  } else if (mapDataType.value === "revenue") {
    // 收入贡献 = 客源数量 × 随机系数(模拟每个地区客人的消费能力差异)
    sortedData = baseData
      .map((item) => ({
        ...item,
        revenue: Math.round(item.value * (0.8 + Math.random() * 0.4) * 100),
      }))
      .sort((a, b) => b.revenue - a.revenue);
  } else {
    // 增长率 = 模拟各地区同比增长率
    sortedData = baseData
      .map((item) => ({
        ...item,
        growth: +(Math.random() * 30 - 5).toFixed(1),
      }))
      .sort((a, b) => b.growth - a.growth);
  }

  return sortedData.slice(0, 5);
});

// 格式化地图数据值显示
const formatMapValue = (item) => {
  if (mapDataType.value === "source") {
    return `${item.value}人`;
  } else if (mapDataType.value === "revenue") {
    return `¥${item.revenue || Math.round(item.value * (0.8 + Math.random() * 0.4) * 100)}`;
  } else {
    return `${item.growth || +(Math.random() * 30 - 5).toFixed(1)}%`;
  }
};

// 初始化收入趋势图
const initRevenueChart = () => {
  const chartDom = document.querySelector("#revenueChartRef");
  if (!chartDom) return;

  if (revenueChart) {
    revenueChart.dispose();
  }
  revenueChart = echarts.init(chartDom);

  const option = {
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "cross",
        crossStyle: {
          color: "#999",
        },
        lineStyle: {
          type: "dashed",
        },
      },
      backgroundColor: "rgba(255, 255, 255, 0.9)",
      borderColor: "#f2f3f5",
      borderWidth: 1,
      textStyle: {
        color: "#1d2129",
      },
      formatter: function (params) {
        let result = params[0].axisValue + "<br/>";
        params.forEach((item) => {
          if (item.seriesName === "收入") {
            result += `${item.marker} ${item.seriesName}: ¥${item.value.toLocaleString()}<br/>`;
          } else {
            result += `${item.marker} ${item.seriesName}: ${item.value}间<br/>`;
          }
        });
        return result;
      },
    },
    legend: {
      data: ["收入", "入住房间"],
      right: 10,
      top: 0,
      textStyle: {
        color: "#4e5969",
      },
      itemWidth: 12,
      itemHeight: 12,
      itemGap: 24,
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
      axisLine: {
        lineStyle: {
          color: "#E5E6EB",
          width: 1,
        },
      },
      axisTick: {
        show: false,
      },
      axisLabel: {
        color: "#4e5969",
        fontSize: 12,
        margin: 12,
      },
    },
    yAxis: [
      {
        type: "value",
        name: "收入",
        min: 0,
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        splitLine: {
          lineStyle: {
            type: "dashed",
            color: "#E5E6EB",
            width: 1,
          },
        },
        axisLabel: {
          color: "#4e5969",
          fontSize: 12,
          formatter: "¥{value}",
        },
      },
      {
        type: "value",
        name: "入住房间",
        min: 0,
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        splitLine: {
          show: false,
        },
        axisLabel: {
          color: "#4e5969",
          fontSize: 12,
          formatter: "{value}间",
        },
      },
    ],
    series: [
      {
        name: "收入",
        type: "bar",
        barWidth: "20%",
        data: [3200, 4500, 5800, 3800, 6000, 8200, 7500],
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: "rgba(22, 93, 255, 0.85)" },
            { offset: 1, color: "rgba(22, 93, 255, 0.3)" },
          ]),
          borderRadius: [4, 4, 0, 0],
        },
      },
      {
        name: "入住房间",
        type: "line",
        smooth: true,
        symbol: "circle",
        symbolSize: 8,
        yAxisIndex: 1,
        data: [32, 45, 58, 38, 60, 82, 75],
        itemStyle: {
          color: "#722ED1",
        },
        lineStyle: {
          width: 3,
          shadowColor: "rgba(114, 46, 209, 0.3)",
          shadowBlur: 10,
          shadowOffsetY: 6,
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: "rgba(114, 46, 209, 0.3)" },
            { offset: 1, color: "rgba(114, 46, 209, 0.05)" },
          ]),
        },
      },
    ],
  };

  revenueChart.setOption(option);
  window.addEventListener("resize", () => {
    revenueChart.resize();
  });
};

// 初始化房型入住率图
const initRoomTypeChart = () => {
  const chartDom = document.querySelector("#roomTypeChartRef");
  if (!chartDom) return;

  if (roomTypeChart) {
    roomTypeChart.dispose();
  }
  roomTypeChart = echarts.init(chartDom);

  const option = {
    tooltip: {
      trigger: "item",
      formatter: "{b}: {c}%",
    },
    legend: {
      orient: "vertical",
      right: 10,
      top: "center",
      textStyle: {
        color: "#6B7280",
      },
    },
    series: [
      {
        name: "入住率",
        type: "pie",
        radius: ["40%", "70%"],
        avoidLabelOverlap: false,
        itemStyle: {
          borderRadius: 10,
          borderColor: "#fff",
          borderWidth: 2,
        },
        label: {
          show: false,
          position: "center",
        },
        emphasis: {
          label: {
            show: true,
            fontSize: 20,
            fontWeight: "bold",
          },
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: "rgba(0, 0, 0, 0.5)",
          },
        },
        labelLine: {
          show: false,
        },
        data: [
          {
            value: 35,
            name: "标准单人房",
            itemStyle: { color: "#165DFF" },
          },
          {
            value: 30,
            name: "标准双人房",
            itemStyle: { color: "#36CFC9" },
          },
          {
            value: 20,
            name: "豪华大床房",
            itemStyle: { color: "#FFA940" },
          },
          {
            value: 15,
            name: "豪华套房",
            itemStyle: { color: "#F759AB" },
          },
        ],
      },
    ],
  };

  roomTypeChart.setOption(option);
  window.addEventListener("resize", () => {
    roomTypeChart.resize();
  });
};

// 地图加载状态
const mapLoading = ref(false);

// 初始化地区分析图表
const initRegionChart = () => {
  const chartDom = document.querySelector("#regionChartRef");
  if (!chartDom) return;

  mapLoading.value = true;

  if (regionChart) {
    regionChart.dispose();
  }
  regionChart = echarts.init(chartDom);

  // 根据数据类型生成不同数据
  const generateMapData = () => {
    const baseData = mapType.value === "china" ? chinaData : guangxiData;

    // 根据时间范围调整数据基础比例
    const timeFactor =
      regionTimeRange.value === "week"
        ? 0.6
        : regionTimeRange.value === "month"
          ? 1
          : 1.5;

    // 按照数据类型生成不同数据
    if (mapDataType.value === "source") {
      // 客源数量
      return baseData.map((item) => ({
        name: item.name,
        value: Math.round(item.value * timeFactor),
        percentage: +(item.percentage * timeFactor).toFixed(1),
      }));
    } else if (mapDataType.value === "revenue") {
      // 收入贡献
      return baseData.map((item) => {
        const revenueFactor = 0.8 + Math.random() * 0.4; // 模拟消费能力系数
        return {
          name: item.name,
          value: Math.round(item.value * timeFactor * revenueFactor * 100),
          rawValue: Math.round(item.value * timeFactor),
          percentage: +(item.percentage * timeFactor).toFixed(1),
          revenueFactor,
        };
      });
    } else {
      // 增长率
      return baseData.map((item) => {
        const growth = +(Math.random() * 30 - 5).toFixed(1); // -5%~25%的增长率
        return {
          name: item.name,
          value: growth,
          rawValue: Math.round(item.value * timeFactor),
          percentage: +(item.percentage * timeFactor).toFixed(1),
          growth,
        };
      });
    }
  };

  // 获取处理后的数据
  const data = generateMapData();

  // 计算最大值和总值
  let maxValue, totalValue;

  if (mapDataType.value === "growth") {
    maxValue = Math.max(...data.map((item) => item.value));
    totalValue = data.reduce((sum, item) => sum + item.rawValue, 0);

    // 重新计算各区域占比百分比
    data.forEach((item) => {
      item.percentage = +((item.rawValue / totalValue) * 100).toFixed(1);
    });
  } else {
    maxValue = Math.max(...data.map((item) => item.value));
    totalValue = data.reduce((sum, item) => sum + item.value, 0);

    // 重新计算各区域占比百分比
    data.forEach((item) => {
      item.percentage = +((item.value / totalValue) * 100).toFixed(1);
    });
  }

  // 创建适合数据类型的视觉映射配置
  const createVisualMap = () => {
    if (mapDataType.value === "source") {
      return {
        show: true,
        type: "piecewise",
        min: 0,
        max: maxValue,
        left: "5%",
        bottom: "5%",
        text: ["高", "低"],
        calculable: true,
        inRange: {
          color: [
            "#e6f7ff",
            "#bae7ff",
            "#91d5ff",
            "#69c0ff",
            "#40a9ff",
            "#1890ff",
            "#096dd9",
          ],
        },
        textStyle: {
          color: "#666",
        },
        formatter: function (value) {
          return value.toFixed(0);
        },
        pieces: [
          {
            min: Math.round(maxValue * 0.8),
            label: `${Math.round(maxValue * 0.8)}以上`,
          },
          {
            min: Math.round(maxValue * 0.6),
            max: Math.round(maxValue * 0.8) - 1,
            label: `${Math.round(maxValue * 0.6)}-${Math.round(maxValue * 0.8)}`,
          },
          {
            min: Math.round(maxValue * 0.4),
            max: Math.round(maxValue * 0.6) - 1,
            label: `${Math.round(maxValue * 0.4)}-${Math.round(maxValue * 0.6)}`,
          },
          {
            min: Math.round(maxValue * 0.2),
            max: Math.round(maxValue * 0.4) - 1,
            label: `${Math.round(maxValue * 0.2)}-${Math.round(maxValue * 0.4)}`,
          },
          {
            min: 1,
            max: Math.round(maxValue * 0.2) - 1,
            label: `1-${Math.round(maxValue * 0.2)}`,
          },
          { max: 0, label: "0" },
        ],
      };
    } else if (mapDataType.value === "revenue") {
      return {
        show: true,
        type: "piecewise",
        min: 0,
        max: maxValue,
        left: "5%",
        bottom: "5%",
        text: ["高", "低"],
        calculable: true,
        inRange: {
          color: [
            "#fff7e6",
            "#ffd591",
            "#ffa940",
            "#fa8c16",
            "#d46b08",
            "#ad4e00",
          ],
        },
        textStyle: {
          color: "#666",
        },
        formatter: function (value) {
          return "¥" + value.toFixed(0);
        },
        pieces: [
          {
            min: Math.round(maxValue * 0.8),
            label: `¥${Math.round(maxValue * 0.8)}以上`,
          },
          {
            min: Math.round(maxValue * 0.6),
            max: Math.round(maxValue * 0.8) - 1,
            label: `¥${Math.round(maxValue * 0.6)}-${Math.round(maxValue * 0.8)}`,
          },
          {
            min: Math.round(maxValue * 0.4),
            max: Math.round(maxValue * 0.6) - 1,
            label: `¥${Math.round(maxValue * 0.4)}-${Math.round(maxValue * 0.6)}`,
          },
          {
            min: Math.round(maxValue * 0.2),
            max: Math.round(maxValue * 0.4) - 1,
            label: `¥${Math.round(maxValue * 0.2)}-${Math.round(maxValue * 0.4)}`,
          },
          {
            min: 1,
            max: Math.round(maxValue * 0.2) - 1,
            label: `¥1-${Math.round(maxValue * 0.2)}`,
          },
          { max: 0, label: "¥0" },
        ],
      };
    } else {
      return {
        show: true,
        type: "continuous",
        min: -5,
        max: 25,
        left: "5%",
        bottom: "5%",
        text: ["高增长", "低增长"],
        calculable: true,
        inRange: {
          color: ["#cf1322", "#ffa39e", "#f0f0f0", "#b7eb8f", "#52c41a"],
        },
        textStyle: {
          color: "#666",
        },
        formatter: function (value) {
          return value.toFixed(1) + "%";
        },
      };
    }
  };

  // 自定义提示框格式
  const createTooltipFormatter = () => {
    if (mapDataType.value === "source") {
      return function (params) {
        if (!params.value && params.value !== 0) return params.name;
        return `${params.name}<br/>客源数量：${params.value}人<br/>占比：${params.data.percentage}%`;
      };
    } else if (mapDataType.value === "revenue") {
      return function (params) {
        if (!params.value && params.value !== 0) return params.name;
        return `${params.name}<br/>收入贡献：¥${params.value}<br/>客源数量：${params.data.rawValue}人<br/>占比：${params.data.percentage}%`;
      };
    } else {
      return function (params) {
        if (!params.value && params.value !== 0) return params.name;
        const growthClass = params.value >= 0 ? "color:green" : "color:red";
        const prefix = params.value >= 0 ? "+" : "";
        return `${params.name}<br/>增长率：<span style="${growthClass}">${prefix}${params.value}%</span><br/>客源数量：${params.data.rawValue}人<br/>占比：${params.data.percentage}%`;
      };
    }
  };

  const option = {
    backgroundColor: "#fff",
    tooltip: {
      trigger: "item",
      formatter: createTooltipFormatter(),
      backgroundColor: "rgba(255, 255, 255, 0.9)",
      borderColor: "#f2f3f5",
      borderWidth: 1,
      padding: [10, 15],
      textStyle: {
        color: "#1d2129",
      },
    },
    visualMap: createVisualMap(),
    series: [
      {
        name: "客源分布",
        type: "map",
        map: mapType.value,
        roam: false, // 禁止拖拽和缩放
        zoom: mapType.value === "china" ? chinaMapZoom.value : 1.1,
        center:
          mapType.value === "china"
            ? [
                chinaMapCenter.value[0],
                chinaMapCenter.value[1] + chinaMapOffsetY.value,
              ]
            : guangxiMapCenter.value, // 根据地图类型设置中心位置
        aspectScale: 0.85,
        scaleLimit: {
          min: 0.8,
          max: 5,
        },
        itemStyle: {
          areaColor: "#fafafa",
          borderColor: "#666666", // 加深边界线颜色
          borderWidth: 1.2, // 增加边界线宽度
        },
        emphasis: {
          itemStyle: {
            areaColor: "#e6f7ff",
            shadowColor: "rgba(0, 0, 0, 0.2)",
            shadowBlur: 10,
            borderWidth: 2, // 增加高亮边框宽度
            borderColor: "#1890ff",
          },
          label: {
            show: true,
            color: "#000",
            fontSize: 14,
            fontWeight: "bold",
          },
        },
        select: {
          itemStyle: {
            areaColor: "#e6f7ff",
          },
        },
        data: data.map((item) => {
          return {
            name: item.name, // 直接使用原始名称，不进行映射
            value: item.value,
            percentage: item.percentage,
            rawValue: item.rawValue || item.value,
            growth: item.growth,
            revenue: item.revenue,
          };
        }),
        label: {
          show: true,
          color: "#333",
          fontSize: 12,
        },
      },
    ],
  };

  // 如果是中国地图，添加南海诸岛配置
  if (mapType.value === "china") {
    // 添加南海诸岛子地图配置
    option.series.push({
      name: "南海诸岛",
      type: "map",
      map: "china",
      // 调整南海诸岛位置和大小
      layoutCenter: nanHaiPosition.value,
      layoutSize: nanHaiSize.value,
      itemStyle: {
        borderColor: "#666666", // 加深边界线颜色
        borderWidth: 1.2, // 增加边界线宽度
        areaColor: "#fafafa",
      },
      emphasis: {
        itemStyle: {
          areaColor: "#e6f7ff",
          borderColor: "#1890ff",
          borderWidth: 2, // 增加高亮边框宽度
        },
        label: {
          show: false,
        },
      },
      label: {
        show: false,
      },
      // 只显示南海诸岛部分
      select: {
        label: {
          show: false,
        },
      },
      roam: false, // 确保禁止交互
      // 使用特殊样式来明确显示这是分离的南海区域
      tooltip: {
        show: false,
      },
      nameMap: {}, // 确保使用与主地图一致的名称映射
      data: [], // 不显示数据
    });

    // 添加南海标题标签
    option.graphic = [
      {
        type: "text",
        right: "10%",
        bottom: "10%",
        style: {
          text: "南海诸岛",
          textAlign: "center",
          fill: "#666",
          fontSize: 12,
        },
      },
    ];
  }

  regionChart.setOption(option);

  // 添加加载完成事件
  regionChart.on("rendered", () => {
    mapLoading.value = false;
  });

  // 强制结束加载状态，以防渲染事件未触发
  setTimeout(() => {
    mapLoading.value = false;
  }, 800);

  window.addEventListener("resize", () => {
    regionChart.resize();
  });
};

// 初始化用户分析图表
const initUserChart = () => {
  const chartDom = document.querySelector("#userChartRef");
  if (!chartDom) return;

  if (userChart) {
    userChart.dispose();
  }
  userChart = echarts.init(chartDom);

  const option =
    userAnalysisTab.value === "age"
      ? {
          tooltip: {
            trigger: "axis",
            axisPointer: {
              type: "shadow",
            },
          },
          grid: {
            left: "3%",
            right: "4%",
            bottom: "3%",
            containLabel: true,
          },
          xAxis: {
            type: "category",
            data: ["18-25", "26-35", "36-45", "46-55", "56-65", "65+"],
            axisLabel: {
              color: "#4e5969",
            },
          },
          yAxis: {
            type: "value",
            axisLabel: {
              color: "#4e5969",
              formatter: "{value}%",
            },
          },
          series: [
            {
              name: "年龄分布",
              type: "bar",
              data: [15, 28, 25, 18, 10, 4],
              itemStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  { offset: 0, color: "#1890ff" },
                  { offset: 1, color: "#36cfc9" },
                ]),
              },
            },
          ],
        }
      : {
          tooltip: {
            trigger: "item",
          },
          legend: {
            orient: "vertical",
            right: 10,
            top: "center",
          },
          series: [
            {
              name: "性别比例",
              type: "pie",
              radius: ["40%", "70%"],
              avoidLabelOverlap: false,
              itemStyle: {
                borderRadius: 10,
                borderColor: "#fff",
                borderWidth: 2,
              },
              label: {
                show: false,
              },
              emphasis: {
                label: {
                  show: true,
                  fontSize: "20",
                  fontWeight: "bold",
                },
              },
              labelLine: {
                show: false,
              },
              data: [
                { value: 55, name: "女性", itemStyle: { color: "#FF69B4" } },
                { value: 45, name: "男性", itemStyle: { color: "#4169E1" } },
              ],
            },
          ],
        };

  userChart.setOption(option);
  window.addEventListener("resize", () => {
    userChart.resize();
  });
};

// 初始化订单趋势图
const initOrderChart = () => {
  const chartDom = document.querySelector("#orderChartRef");
  if (!chartDom) return;

  if (orderChart) {
    orderChart.dispose();
  }
  orderChart = echarts.init(chartDom);

  // 根据时间范围获取不同的数据
  const getDataByTimeRange = () => {
    const dataMap = {
      week: {
        xAxis: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
        newOrders: [32, 45, 53, 42, 58, 68, 75],
        completedOrders: [28, 40, 48, 38, 52, 60, 68],
        cancelledOrders: [4, 5, 5, 4, 6, 8, 7],
      },
      month: {
        xAxis: ["第1周", "第2周", "第3周", "第4周"],
        newOrders: [180, 220, 260, 290],
        completedOrders: [160, 195, 230, 260],
        cancelledOrders: [20, 25, 30, 30],
      },
      year: {
        xAxis: [
          "1月",
          "2月",
          "3月",
          "4月",
          "5月",
          "6月",
          "7月",
          "8月",
          "9月",
          "10月",
          "11月",
          "12月",
        ],
        newOrders: [150, 130, 180, 200, 230, 250, 270, 280, 300, 320, 350, 380],
        completedOrders: [
          130, 120, 160, 180, 210, 230, 250, 260, 280, 300, 330, 350,
        ],
        cancelledOrders: [20, 10, 20, 20, 20, 20, 20, 20, 20, 20, 20, 30],
      },
    };
    return dataMap[orderTrendTimeRange.value] || dataMap.week;
  };

  const data = getDataByTimeRange();

  const option = {
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow",
        shadowStyle: {
          color: "rgba(0, 0, 0, 0.05)",
        },
      },
      backgroundColor: "rgba(255, 255, 255, 0.9)",
      borderColor: "#f2f3f5",
      borderWidth: 1,
      textStyle: {
        color: "#1d2129",
      },
      formatter: function (params) {
        let result = params[0].axisValue + "<br/>";
        params.forEach((item) => {
          result += `${item.marker} ${item.seriesName}: ${item.value}单<br/>`;
        });
        return result;
      },
    },
    legend: {
      data: ["新增订单", "已完成", "已取消"],
      bottom: "0%",
      left: "center",
      itemWidth: 10,
      itemHeight: 10,
      textStyle: {
        color: "#4e5969",
      },
      itemGap: 20,
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "15%",
      top: "8%",
      containLabel: true,
    },
    xAxis: {
      type: "category",
      data: data.xAxis,
      axisLine: {
        lineStyle: {
          color: "#E5E6EB",
        },
      },
      axisTick: {
        show: false,
      },
      axisLabel: {
        color: "#4e5969",
        fontSize: 12,
        margin: 12,
      },
    },
    yAxis: {
      type: "value",
      name: "订单数",
      axisLine: {
        show: false,
      },
      axisTick: {
        show: false,
      },
      splitLine: {
        lineStyle: {
          type: "dashed",
          color: "#E5E6EB",
        },
      },
      axisLabel: {
        color: "#4e5969",
        fontSize: 12,
        formatter: "{value}单",
      },
    },
    series: [
      {
        name: "新增订单",
        type: "bar",
        stack: "订单",
        emphasis: {
          focus: "series",
        },
        barWidth: 20,
        data: data.newOrders,
        itemStyle: {
          color: "#165DFF",
          borderRadius: [4, 4, 0, 0],
        },
      },
      {
        name: "已完成",
        type: "bar",
        stack: "订单",
        emphasis: {
          focus: "series",
        },
        data: data.completedOrders,
        itemStyle: {
          color: "#36CFC9",
          borderRadius: [4, 4, 0, 0],
        },
      },
      {
        name: "已取消",
        type: "bar",
        stack: "订单",
        emphasis: {
          focus: "series",
        },
        data: data.cancelledOrders,
        itemStyle: {
          color: "#F53F3F",
          borderRadius: [4, 4, 0, 0],
        },
      },
    ],
  };

  orderChart.setOption(option);
  window.addEventListener("resize", () => {
    orderChart.resize();
  });
};

// 初始化酒店运营指标五角图
const initBusinessIndicatorChart = () => {
  const chartDom = document.querySelector("#businessIndicatorRef");
  if (!chartDom) return;

  if (businessIndicatorChart) {
    businessIndicatorChart.dispose();
  }
  businessIndicatorChart = echarts.init(chartDom);

  const option = {
    tooltip: {
      trigger: "item",
      formatter: "{a} <br/>{b}: {c} ({d}%)",
    },
    radar: {
      indicator: [
        { name: "入住率", max: 100 },
        { name: "客户满意度", max: 100 },
        { name: "员工效率", max: 100 },
        { name: "收入增长", max: 100 },
        { name: "重复入住率", max: 100 },
      ],
      radius: "65%",
      splitNumber: 5,
      axisName: {
        color: "#4e5969",
        fontSize: 12,
      },
      splitArea: {
        areaStyle: {
          color: ["rgba(255, 255, 255, 0.9)", "rgba(245, 245, 245, 0.9)"],
        },
      },
      splitLine: {
        lineStyle: {
          color: "#E5E6EB",
        },
      },
      axisLine: {
        lineStyle: {
          color: "#E5E6EB",
        },
      },
    },
    legend: {
      data: ["本酒店", "行业平均"],
      bottom: 0,
      left: "center",
      textStyle: {
        color: "#4e5969",
      },
      itemWidth: 12,
      itemHeight: 12,
    },
    series: [
      {
        name: "运营指标对比",
        type: "radar",
        emphasis: {
          lineStyle: {
            width: 4,
          },
        },
        data: [
          {
            value: [85, 82, 78, 65, 72],
            name: "本酒店",
            symbol: "circle",
            symbolSize: 6,
            lineStyle: {
              width: 2,
              color: "#165DFF",
            },
            areaStyle: {
              color: "rgba(22, 93, 255, 0.2)",
            },
            itemStyle: {
              color: "#165DFF",
            },
          },
          {
            value: [80, 75, 80, 70, 60],
            name: "行业平均",
            symbol: "circle",
            symbolSize: 6,
            lineStyle: {
              width: 2,
              color: "#36CFC9",
            },
            areaStyle: {
              color: "rgba(54, 207, 201, 0.2)",
            },
            itemStyle: {
              color: "#36CFC9",
            },
          },
        ],
      },
    ],
  };

  businessIndicatorChart.setOption(option);
  window.addEventListener("resize", () => {
    businessIndicatorChart.resize();
  });
};

// 监听图表类型变化
watch(
  [
    revenueTrendType,
    roomAnalysisType,
    mapType,
    userAnalysisTab,
    orderTrendTimeRange,
    mapDataType,
    regionTimeRange,
  ],
  () => {
    nextTick(() => {
      initRevenueChart();
      initRoomTypeChart();
      initRegionChart();
      initUserChart();
      initOrderChart();
      initBusinessIndicatorChart();
    });
  },
);

// 组件挂载时初始化
onMounted(async () => {
  // 注册地图数据
  try {
    // 使用 china geo json 数据
    const chinaResponse = await fetch(
      "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json",
    );
    const chinaJson = await chinaResponse.json();

    // 确保使用完整省份名称
    if (chinaJson && chinaJson.features) {
      for (const feature of chinaJson.features) {
        if (feature.properties && feature.properties.name) {
          // 将地图数据中的简称替换为全称，保持与我们的数据一致
          const fullName = getFullProvinceName(feature.properties.name);
          if (fullName) {
            feature.properties.name = fullName;
          }
        }
      }
    }

    echarts.registerMap("china", chinaJson);

    // 使用广西 geo json 数据
    const guangxiResponse = await fetch(
      "https://geo.datav.aliyun.com/areas_v3/bound/450000_full.json",
    );
    const guangxiJson = await guangxiResponse.json();

    // 确保使用完整城市名称
    if (guangxiJson && guangxiJson.features) {
      for (const feature of guangxiJson.features) {
        if (feature.properties && feature.properties.name) {
          // 将地图数据中的简称替换为全称，保持与我们的数据一致
          const fullName = getFullCityName(feature.properties.name);
          if (fullName) {
            feature.properties.name = fullName;
          }
        }
      }
    }

    echarts.registerMap("guangxi", guangxiJson);
  } catch (error) {
    console.error("加载地图数据失败:", error);
  }

  // 初始化所有图表
  nextTick(() => {
    initRevenueChart();
    initRoomTypeChart();
    initRegionChart();
    initUserChart();
    initOrderChart();
    initBusinessIndicatorChart();
  });

  // 组件卸载时清理
  onUnmounted(() => {
    // 移除图表中添加的事件监听器
    window.removeEventListener("resize", () => {});

    // 销毁所有图表实例
    if (revenueChart) revenueChart.dispose();
    if (roomTypeChart) roomTypeChart.dispose();
    if (regionChart) regionChart.dispose();
    if (userChart) userChart.dispose();
    if (orderChart) orderChart.dispose();
    if (businessIndicatorChart) businessIndicatorChart.dispose();
  });

  // 加载保存的分析结果
  loadSavedAnalysis();
});

// 获取省份全称
const getFullProvinceName = (shortName) => {
  // 简称到全称的映射表
  const shortToFullMap = {
    北京: "北京市",
    天津: "天津市",
    河北: "河北省",
    山西: "山西省",
    内蒙古: "内蒙古自治区",
    辽宁: "辽宁省",
    吉林: "吉林省",
    黑龙江: "黑龙江省",
    上海: "上海市",
    江苏: "江苏省",
    浙江: "浙江省",
    安徽: "安徽省",
    福建: "福建省",
    江西: "江西省",
    山东: "山东省",
    河南: "河南省",
    湖北: "湖北省",
    湖南: "湖南省",
    广东: "广东省",
    广西: "广西壮族自治区",
    海南: "海南省",
    重庆: "重庆市",
    四川: "四川省",
    贵州: "贵州省",
    云南: "云南省",
    西藏: "西藏自治区",
    陕西: "陕西省",
    甘肃: "甘肃省",
    青海: "青海省",
    宁夏: "宁夏回族自治区",
    新疆: "新疆维吾尔自治区",
    香港: "香港特别行政区",
    澳门: "澳门特别行政区",
    台湾: "台湾省",
  };

  return shortToFullMap[shortName] || shortName;
};

// 获取城市全称
const getFullCityName = (shortName) => {
  // 广西城市简称到全称的映射表
  const cityToFullMap = {
    南宁: "南宁市",
    桂林: "桂林市",
    柳州: "柳州市",
    贵港: "贵港市",
    玉林: "玉林市",
    北海: "北海市",
    钦州: "钦州市",
    防城港: "防城港市",
    崇左: "崇左市",
    百色: "百色市",
    河池: "河池市",
    来宾: "来宾市",
    贺州: "贺州市",
    梧州: "梧州市",
  };

  return cityToFullMap[shortName] || shortName;
};

// AI分析相关
const aiAnalysisLoading = ref(false);
const aiAnalysisResult = ref("");
const aiAnalysisTime = ref("");

// 从本地存储加载最近的AI分析
const loadSavedAnalysis = () => {
  const savedAnalysis = localStorage.getItem("hotelAIAnalysis");
  if (savedAnalysis) {
    try {
      const analysisData = JSON.parse(savedAnalysis);
      aiAnalysisResult.value = analysisData.result;
      aiAnalysisTime.value = analysisData.time;
    } catch (e) {
      console.error("解析本地AI分析数据失败:", e);
    }
  }
};

// 生成AI分析
const generateAIAnalysis = async () => {
  aiAnalysisLoading.value = true;
  try {
    // 模拟调用Deepseek API的延迟
    await new Promise((resolve) => setTimeout(resolve, 1500));

    // 这里是模拟的AI分析结果，实际实现中应该调用Deepseek API
    const analysisResults = [
      "根据您的酒店数据分析，工作日入住率偏低，建议针对商务客户推出特别套餐。周末客流量高峰期，可适当提高房价。客户反馈显示房间清洁度评分较低，建议加强培训并设立质检机制。网络评价中餐饮服务获赞较多，可进一步强化此优势并做营销推广。为提高复住率，可建立会员积分体系，并针对老客户提供个性化服务。",
      "数据显示您的酒店淡旺季差异明显，建议淡季期间与本地旅游景点合作推出套餐，增加吸引力。客户画像分析显示家庭客户比例上升，可考虑增设亲子房型和设施。在线预订占比较低，建议优化网站体验并加强与OTA平台合作。客户投诉主要集中在噪音问题上，建议进行隔音设施升级。转化率数据显示价格是决定因素，可实施更灵活的定价策略。",
      "AI分析显示您的酒店有三个关键改进点：首先，入住高峰时段前台人手不足，建议调整排班或增设自助入住设备；其次，客户复住率低于行业平均，可通过个性化服务和会员福利提升；第三，餐饮收入占比低，建议改进菜单并考虑与知名餐饮品牌合作。数据还显示您的酒店在社交媒体曝光不足，建议增加内容营销投入，提高品牌知名度。",
    ];

    // 随机选择一条分析结果
    aiAnalysisResult.value =
      analysisResults[Math.floor(Math.random() * analysisResults.length)];
    aiAnalysisTime.value = new Date().toLocaleString();

    // 保存到本地存储
    localStorage.setItem(
      "hotelAIAnalysis",
      JSON.stringify({
        result: aiAnalysisResult.value,
        time: aiAnalysisTime.value,
      }),
    );

    ElMessage.success("AI分析完成");
  } catch (error) {
    console.error("AI分析失败:", error);
    ElMessage.error("AI分析生成失败，请稍后重试");
  } finally {
    aiAnalysisLoading.value = false;
  }
};

// 地图设置面板
const showMapSettings = ref(false);
const nanHaiPositionLeft = computed({
  get: () => parseInt(nanHaiPosition.value[0]),
  set: (val) => (nanHaiPosition.value[0] = `${val}%`),
});
const nanHaiPositionTop = computed({
  get: () => parseInt(nanHaiPosition.value[1]),
  set: (val) => (nanHaiPosition.value[1] = `${val}%`),
});
const nanHaiSizeNum = computed({
  get: () => parseInt(nanHaiSize.value),
  set: (val) => (nanHaiSize.value = `${val}%`),
});

// 监听地图设置变化，自动更新地图
watch(
  [
    chinaMapZoom,
    chinaMapOffsetY,
    chinaMapCenter,
    guangxiMapCenter,
    nanHaiPosition,
    nanHaiSize,
  ],
  () => {
    nextTick(() => {
      initRegionChart();
    });
  },
);

// 地图设置
const resetMapSettings = () => {
  if (mapType.value === "china") {
    chinaMapZoom.value = 1.2;
    chinaMapOffsetY.value = 0;
    chinaMapCenter.value = [104.5, 36.5];
    nanHaiPosition.value = ["80%", "85%"];
    nanHaiSize.value = "15%";
  } else {
    guangxiMapCenter.value = [108.320004, 22.82402];
  }
  Message.success("已重置地图设置");
};
</script>

<style scoped>
.dashboard-container {
  min-height: 100vh;
  background-color: var(--color-bg-2);
  padding: 16px;
}

.dashboard-content {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.dashboard-main-container {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 16px;
}

@media (max-width: 1200px) {
  .dashboard-main-container {
    grid-template-columns: 1fr;
  }
}

.dashboard-main {
  width: 100%;
}

.dashboard-sidebar {
  width: 100%;
}

.chart-card {
  height: 100%;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.chart-card:hover {
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
}

.sidebar-card {
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
  transition: all 0.3s ease;
}

.sidebar-card:hover {
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
}

.chart-container {
  height: 320px;
  width: 100%;
}

.map-container {
  height: 400px;
  position: relative;
  overflow: hidden;
  border-radius: 4px;
}

@media (max-width: 1400px) {
  .map-container {
    height: 360px;
  }
}

@media (max-width: 1200px) {
  .map-container {
    height: 320px;
  }
}

.map-chart-card {
  overflow: hidden;
}

.stat-card {
  border: none;
  border-radius: 8px;
  transition: all 0.3s ease;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
}

.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
}

.revenue-card {
  background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
}

.orders-card {
  background: linear-gradient(135deg, #f6ffed 0%, #b7eb8f 100%);
}

.occupancy-card {
  background: linear-gradient(135deg, #f9f0ff 0%, #d3adf7 100%);
}

.members-card {
  background: linear-gradient(135deg, #fff7e6 0%, #ffd591 100%);
}

.stat-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  font-size: 24px;
}

.revenue-icon {
  background-color: rgba(24, 144, 255, 0.1);
  color: #1890ff;
}

.orders-icon {
  background-color: rgba(82, 196, 26, 0.1);
  color: #52c41a;
}

.occupancy-icon {
  background-color: rgba(114, 46, 209, 0.1);
  color: #722ed1;
}

.members-icon {
  background-color: rgba(250, 173, 20, 0.1);
  color: #faad14;
}

.stat-footer {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.todo-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px;
  background-color: var(--color-bg-1);
  border-radius: 8px;
  transition: background-color 0.3s;
}

.todo-item:hover {
  background-color: var(--color-bg-2);
}

.ai-analysis-content {
  min-height: 280px; /* 从 160px 增加到 260px */
  max-height: 285px; /* 添加最大高度限制 */
  overflow-y: auto; /* 添加垂直滚动条，当内容超过高度时 */
}

/* 当有分析结果时可以根据内容自适应高度 */
.ai-analysis-content:has(.bg-gray-50) {
  height: auto;
}

.arco-timeline-item {
  padding-bottom: 20px;
}

.arco-timeline-item:last-child {
  padding-bottom: 0;
}

/* 暗黑模式适配 */
.dark .revenue-card {
  background: linear-gradient(135deg, #111d2c 0%, #15395b 100%);
}

.dark .orders-card {
  background: linear-gradient(135deg, #162312 0%, #1d3712 100%);
}

.dark .occupancy-card {
  background: linear-gradient(135deg, #120338 0%, #22075e 100%);
}

.dark .members-card {
  background: linear-gradient(135deg, #2b2111 0%, #3c2a0f 100%);
}

.dark .stat-footer {
  border-top-color: rgba(255, 255, 255, 0.1);
}

.dark .todo-item {
  background-color: rgba(255, 255, 255, 0.04);
}

.dark .todo-item:hover {
  background-color: rgba(255, 255, 255, 0.08);
}

.map-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}

.map-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.7);
  z-index: 10;
  color: #1890ff;
  font-size: 14px;
}

/* 地图交互样式 */
:deep(.map-chart-card .arco-card-body) {
  padding: 0;
  height: 100%;
}

:deep(.map-chart-card .arco-card-header) {
  border-bottom: none;
  padding: 16px 20px;
}

:deep(.map-chart-card .arco-card-header-title) {
  font-size: 16px;
  font-weight: 500;
}

/* 地图工具提示样式 */
:deep(.echarts-tooltip) {
  background: rgba(255, 255, 255, 0.9) !important;
  border-radius: 4px !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
  padding: 8px 12px !important;
  color: #333 !important;
  font-size: 14px !important;
  line-height: 1.5 !important;
  border: 1px solid #f0f0f0 !important;
}

.map-legend {
  position: absolute;
  top: 20px;
  right: 20px;
  background-color: rgba(255, 255, 255, 0.8);
  padding: 10px;
  border-radius: 6px;
  width: 180px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  z-index: 10;
  border: 1px solid #f0f0f0;
}

.rank-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  font-size: 10px;
  margin-right: 6px;
  color: #fff;
  font-weight: bold;
}

.rank-1 {
  background-color: #f5222d;
}

.rank-2 {
  background-color: #fa8c16;
}

.rank-3 {
  background-color: #faad14;
}

.rank-4 {
  background-color: #a0d911;
}

.rank-5 {
  background-color: #52c41a;
}

.dark .map-legend {
  background-color: rgba(36, 37, 37, 0.8);
  border-color: #303030;
}

.map-settings-panel {
  padding: 16px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  margin-bottom: 16px;
  border: 1px solid #f0f0f0;
}

.dark .map-settings-panel {
  background-color: var(--color-bg-2);
  border-color: var(--color-border-2);
}

.settings-title {
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 12px;
  color: #1d2129;
  border-left: 3px solid #165dff;
  padding-left: 8px;
}

.dark .settings-title {
  color: var(--color-text-1);
  border-left-color: #4080ff;
}

.settings-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding: 4px 0;
}

.settings-label {
  font-weight: 500;
  width: 80px;
  color: #4e5969;
}

.dark .settings-label {
  color: var(--color-text-2);
}

/* 确保地图容器高度足够 */
.map-container {
  height: 450px;
}

@media (max-width: 1400px) {
  .map-container {
    height: 400px;
  }
}

@media (max-width: 1200px) {
  .map-container {
    height: 360px;
  }
}
</style>
